import { Injectable } from '@nestjs/common';
import { CreateDogDto } from './dto/create-dog.dto';
import { UpdateDogDto } from './dto/update-dog.dto';
import { Model, ClientSession, startSession } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { Dog } from './entities/dog.entity';
import { randomUUID } from 'crypto';
import { CreateDogManyDto } from './dto/create-dog-many.dto';

@Injectable()
export class DogService {

  constructor(
    @InjectModel(Dog.name)
    private dogModel: Model<Dog>
    // @InjectEntityManager()
    // private readonly manager: EntityManager,
  ) {}
  
  // 创建一条
  async create(createDogDto: CreateDogDto) {
    const dog = new this.dogModel(createDogDto);
    // console.log(dog, 8888)
    const timestamp = new Date().getTime();
    dog.id = `${timestamp}${randomUUID()}`;
    console.log(timestamp, dog)
    const result = await this.dogModel.insertOne(dog);
    // const result = await dog.save();
    return result
  }

  // 创建多条
  async createMany(createDogDto: CreateDogManyDto) {
    const timestamp = new Date().getTime();
    const dogsToInsert = createDogDto.list.map(dogDto => ({
      ...dogDto,
      id: `${timestamp}-${randomUUID()}`,
    }));
    const result = await this.dogModel.insertMany(dogsToInsert);
    return result
  }

  // 寻找全部
  async findAll(page: number = 1, limit: number = 3) {
    // const skip = (page - 1) * limit;
    // const query = { name: { $regex: /222/} };

    const result = await this.dogModel.find()
    console.log(result)
    return result
  }

  // 分页查询
  async findPaging(page: number = 1, limit: number = 3) {
    const skip = (page - 1) * limit;
    const query = { 
      products: {
        $elemMatch: { 
          name: { $regex: /222/ }
        }
      }
    }

    const [result, count] = await Promise.all([
      this.dogModel.find(query).skip(skip).limit(limit),
      this.dogModel.countDocuments(query),
    ]);
    return { result, count }
  }

  // 统计查询
  async findMeAll() {
    const result = await this.dogModel.aggregate([
      // 1 - 添加$unwind阶段以将products数组中的条目分隔成单个文档：
      {
        $unwind: {
          path: "$products",
        },
      },
      // 2 - 添加一个$match阶段，用于匹配products.price值大于$15元的产品：
      {
        $match: {
          "products.price": {
            $gt: 15,
          },
        },
      },
      // 3 - 添加$group阶段以按prod_id字段的值对订单进行分组。 在此阶段，添加聚合操作，在结果文档中创建以下字段：
      {
        $group: {
          _id: "$products.prod_id",
          product: { $first: "$products.name" },
          total_value: { $sum: "$products.price" },
          number: { $sum: 1 },
        },
      },
      // 4 - 添加$set阶段，以根据$group阶段设置的_id字段中的值重新创建product_id字段：
      {
        $set: {
          product_id: "$_id",
        }
      },
      // 5 - 添加一个$unset阶段。 $unset阶段从结果文档（即是$group阶段第三步）中删除_id字段：
      {
        $unset: ["_id"]
      }
    ])
    // const result = await this.dogModel.find()
    console.log(result)
    return result
  }

  async findOne(id: string) {
    // const result = await this.manager.transaction(async (transactionalEntityManager) => {
    //   const list = await transactionalEntityManager.find()
    //   const one = await transactionalEntityManager.findById(id)
    //   const reslut = {
    //     list,
    //     one
    //   }
    //   return reslut
    // })
    const result = this.dogModel.findById(id)
    console.log(result)
    return result;
  }

  update(id: string, updateDogDto: UpdateDogDto) {
    return this.dogModel.findByIdAndUpdate(
      id,
      updateDogDto,
      {
        returnOriginal: false
      }
    );
  }

  remove(id: string) {
    return this.dogModel.findByIdAndDelete(id);
  }

  // 示例事务方法
  async performTransaction(createDogDto: CreateDogDto, updateDogDto: UpdateDogDto): Promise<void> {

    const session = await this.dogModel.db.startSession();  // 1. 创建会话
    // console.log(this.dogModel.db, 'this.dogModel.dbthis.dogModel.dbthis.dogModel.dbthis.dogModel.db')
    console.log('---------------------------------------------');
    // console.log(session, 'sessionsessionsessionsessionsessionsessionsessionsessionsessionsessionses')
    // const transactionOptions = {
    //   readConcern: { level: 'snapshot' },
    //   writeConcern: { w: 'majority' },
    //   readPreference: 'primary'
    // };

    session.startTransaction();
    console.log('111111111111111')
    try {
      console.log('2222222222222222')
      
      // 创建一个新的数据
      const dog = new this.dogModel(createDogDto);
      const result = await this.dogModel.insertOne(
        dog,
        {
          session,
        }
      );

      console.log('新增事务完成', result)
      // 更新一个已有的数据
      await this.dogModel.findByIdAndUpdate(
        updateDogDto.id,
        updateDogDto,
        {
          returnOriginal: true,
          session,
        }
      );
      console.log('更新事务完成')
      console.log('Transaction successfully committed.');
      // 提交事务
      await session.commitTransaction();
    } catch (error) {
      console.log(error)
      // console.log('333333333333333333333333')
      // 带错误类型判断的重试逻辑
      // if (error.errorLabels?.includes('TransientTransactionError')) {
      //   return this.performTransaction(createDogDto, updateDogDto);
      // }
      // 回滚事务
      await session.abortTransaction();
      console.log('333333333333333333333333')
      console.log(`Transaction failed: ${error.message}`)
      throw error;
    } finally {
      console.log('4444444444444444444444444444')
      // 结束会话
      session.endSession();
    }
  }
}
